/*
 *    Copyright 2009 Daniel Hayes
 *    This file is part of PreCT.
 *
 *    PreCT is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    PreCT is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with PreCT.  If not, see <http://www.gnu.org/licenses/>
 */

function Scramblers(){}

Scramblers.prototype.scramble = function(puz){
    var scramble = "";
	puz = puz.replace("-BLD","").replace("-OH","");
	
    if (puz == "2x2x2") {
        scramble = this.scrambleCube(2, 20);
    }
    else 
        if (puz == "3x3x3") {
            scramble = this.scrambleCube(3, 35);
    }
    else 
        if (puz == "4x4x4") {
            scramble = this.scrambleCube(4, 40);
    }
    else 
        if (puz == "5x5x5") {
            scramble = this.scrambleCube(5, 60);
    }
    else 
        if (puz == "6x6x6") {
            scramble = this.scrambleCube(6, 80);
    }
    else 
        if (puz == "7x7x7") {
            scramble = this.scrambleCube(7, 100);
    }
    else 
        if (puz == "Megaminx") {
            scramble = this.scrambleMegaminx();
    }
    else 
        if (puz == "Pyraminx") {
            scramble = this.scramblePyraminx();
    }
    else 
        if (puz == "Square-1") {
            scramble = this.scrambleSquare1();
    }
    else 
        if (puz == "UFO") {
            scramble = this.scrambleUFO();
    }
	
	return scramble;
}

/* Generate megaminx scrambles */
Scramblers.prototype.scrambleMegaminx = function(){
    var s = '';
    for (var i = 0; i < 7; i++) {
        for (var j = 0; j < 10; j++) {
            if (j % 2 == 1) {
                s += 'D';
            }
            else {
                s += 'R';
            }
            if (Math.floor(Math.random() * 2) == 0) {
                s += '--';
            }
            else {
                s += '++';
            }
            s += ' ';
        }
        if (Math.floor(Math.random() * 2) == 0) {
            s += 'U';
        }
        else {
            s += 'U\'';
        }
        if (i != 7) {
            s += '<br>';
        }
    }
    return s;
}

/* Cube scrambler written by Jaap Scherphuis,  jaapsch a t yahoo d o t com
 Available from the WCA website at http://www.worldcubeassociation.org/regulations/#scrambling */
Scramblers.prototype.scrambleCube = function(size, seqlen){
    var mult = true;
    
    //tl=number of allowed moves (twistable layers) on axis -- middle layer ignored
    var tl = size;
    if (mult || (size & 1) != 0) 
        tl--;
    //set up bookkeeping
    var axsl = new Array(tl); // movement of each slice/movetype on this axis
    var axam = new Array(0, 0, 0); // number of slices moved each amount
    var la; // last axis moved
    // initialise this scramble
    la = -1;
    seq = new Array(); // moves generated so far
    // reset slice/direction counters
    for (var i = 0; i < tl; i++) 
        axsl[i] = 0;
    axam[0] = axam[1] = axam[2] = 0;
    var moved = 0;
    
    // while generated sequence not long enough
    while (seq.length + moved < seqlen) {
        var ax, sl, q;
        do {
            do {
                // choose a random axis
                ax = Math.floor(Math.random() * 3);
                // choose a random move type on that axis
                sl = Math.floor(Math.random() * tl);
                // choose random amount
                q = Math.floor(Math.random() * 3);
            }
            while (ax == la && axsl[sl] != 0); // loop until have found an unused movetype
        }
        while (ax == la // loop while move is reducible: reductions only if on same axis as previous moves
 &&
        !mult // multislice moves have no reductions so always ok
 &&
        tl == size // only even-sized cubes have reductions (odds have middle layer as reference)
 &&
        (2 * axam[0] == tl || // reduction if already have half the slices move in same direction
        2 * axam[1] == tl ||
        2 * axam[2] == tl ||
        (2 * (axam[q] + 1) == tl // reduction if move makes exactly half the slices moved in same direction and
 &&
        axam[0] + axam[1] + axam[2] - axam[q] > 0 // some other slice also moved
)));
        
        // if now on different axis, dump cached moves from old axis
        if (ax != la) {
            this.appendmoves(seq, axsl, tl, la);
            // reset slice/direction counters
            for (var i = 0; i < tl; i++) 
                axsl[i] = 0;
            axam[0] = axam[1] = axam[2] = 0;
            moved = 0;
            // remember new axis
            la = ax;
        }
        
        // adjust counters for this move
        axam[q]++;// adjust direction count
        moved++;
        axsl[sl] = q + 1;// mark the slice has moved amount
    }
    // dump the last few moves
    this.appendmoves(seq, axsl, tl, la);
    
    // do a random cube orientation if necessary
    seq[seq.length] = 0;
    
    var s = "", j;
    for (var i = 0; i < seq.length - 1; i++) {
        if (i != 0) 
            s += " ";
        var k = seq[i] >> 2;
        
        j = k % 6;
        k = (k - j) / 6;
        if (k && size <= 5 && !mult) {
            s += "dlburf".charAt(j); // use lower case only for inner slices on 4x4x4 or 5x5x5
        }
        else {
            if (size <= 5 && mult) {
                s += "DLBURF".charAt(j);
                if (k) 
                    s += "w"; // use w only for double layers on 4x4x4 and 5x5x5
            }
            else {
                if (k) 
                    s += (k + 1);
                s += "DLBURF".charAt(j);
            }
        }
        
        j = seq[i] & 3;
        if (j != 0) 
            s += " 2'".charAt(j);
    }
    
    return s;
}

/* Needed for scrambleCube function */
Scramblers.prototype.appendmoves = function(sq, axsl, tl, la){
    for (var sl = 0; sl < tl; sl++) { // for each move type
        if (axsl[sl]) { // if it occurs
            var q = axsl[sl] - 1;
            
            // get semi-axis of this move
            var sa = la;
            var m = sl;
            if (sl + sl + 1 >= tl) { // if on rear half of this axis
                sa += 3; // get semi-axis (i.e. face of the move)
                m = tl - 1 - m; // slice number counting from that face
                q = 2 - q; // opposite direction when looking at that face
            }
            // store move
            sq[sq.length] = (m * 6 + sa) * 4 + q;
        }
    }
}

/* Square-1 scrambler written by Jaap Scherphuis,  jaapsch a t yahoo d o t com
 Available from the WCA website at http://www.worldcubeassociation.org/regulations/#scrambling */
Scramblers.prototype.scrambleSquare1 = function(){
    var i, j, ls, f;
    var seqlen = 40;
    posit = new Array(0, 0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11, 11, 12, 13, 13, 14, 15, 15);
    ls = -1;
    seq = new Array();
    f = 0;
    for (i = 0; i < seqlen; i++) {
        do {
            if (ls == 0) {
                j = Math.floor(Math.random() * 22) - 11;
                if (j >= 0) 
                    j++;
            }
            else 
                if (ls == 1) {
                    j = Math.floor(Math.random() * 12) - 11;
                }
                else 
                    if (ls == 2) {
                        j = 0;
                    }
                    else {
                        j = Math.floor(Math.random() * 23) - 11;
                    }
            // if past second twist, restrict bottom layer
        }
        while ((f > 1 && j >= -6 && j < 0) || this.doMoveForSquare1(j, posit));
        if (j > 0) 
            ls = 1;
        else 
            if (j < 0) 
                ls = 2;
            else {
                ls = 0;
                f++;
            }
        seq[i] = j;
    }
    
    var s = "", k, l = -1;
    for (i = 0; i < seq.length; i++) {
        k = seq[i];
        if (k == 0) {
            if (l == -1) 
                s += "(0,0)  ";
            if (l == 1) 
                s += "0)  ";
            if (l == 2) 
                s += ")  ";
            l = 0;
        }
        else 
            if (k > 0) {
                s += "(" + (k > 6 ? k - 12 : k) + ",";
                l = 1;
            }
            else 
                if (k < 0) {
                    if (l <= 0) 
                        s += "(0,";
                    s += (k <= -6 ? k + 12 : k);
                    l = 2;
                }
    }
    if (l == 1) 
        s += "0";
    if (l != 0) 
        s += ")";
    return s;
}

/* Needed for scrambleSquare1 functions */
Scramblers.prototype.doMoveForSquare1 = function(m, posit){
    var i, c, t, f = m;
    //do move f
    if (f == 0) {
        for (i = 0; i < 6; i++) {
            c = posit[i + 12];
            posit[i + 12] = posit[i + 6];
            posit[i + 6] = c;
        }
    }
    else 
        if (f > 0) {
            f = 12 - f;
            if (posit[f] == posit[f - 1]) 
                return true;
            if (f < 6 && posit[f + 6] == posit[f + 5]) 
                return true;
            if (f > 6 && posit[f - 6] == posit[f - 7]) 
                return true;
            if (f == 6 && posit[0] == posit[11]) 
                return true;
            t = new Array();
            for (i = 0; i < 12; i++) 
                t[i] = posit[i];
            c = f;
            for (i = 0; i < 12; i++) {
                posit[i] = t[c];
                if (c == 11) 
                    c = 0;
                else 
                    c++;
            }
        }
        else 
            if (f < 0) {
                f = -f;
                if (posit[f + 12] == posit[f + 11]) 
                    return true;
                if (f < 6 && posit[f + 18] == posit[f + 17]) 
                    return true;
                if (f > 6 && posit[f + 6] == posit[f + 5]) 
                    return true;
                if (f == 6 && posit[12] == posit[23]) 
                    return true;
                t = new Array();
                for (i = 0; i < 12; i++) 
                    t[i] = posit[i + 12];
                c = f;
                for (i = 0; i < 12; i++) {
                    posit[i + 12] = t[c];
                    if (c == 11) 
                        c = 0;
                    else 
                        c++;
                }
            }
    return false;
}

/* UFO scrambler written by Jaap Scherphuis,  jaapsch a t yahoo d o t com
 Available from the WCA website at http://www.worldcubeassociation.org/regulations/#scrambling */
Scramblers.prototype.scrambleUFO = function(){
    var seqlen = 20;
    var lm = -1;
    // initialise this scramble
    
    seq = new Array(); // moves generated so far
    // while generated sequence not long enough
    while (seq.length < seqlen) {
    
        // choose a different move than previous one
        var m;
        do {
            m = Math.floor(Math.random() * 4); // U, C,B,A
        }
        while (m == lm);
        
        // choose random amount
        var q = (m == 0) ? Math.floor(Math.random() * 5) + 1 : 1;
        
        // store move
        seq[seq.length] = q * 4 + m;
        
        lm = m;
    }
    
    var s = "";
    for (var i = 0; i < seq.length; i++) {
        if (i != 0) 
            s += " ";
        var q = seq[i] >> 2;
        var m = seq[i] & 3;
        s += "UCBA".charAt(m);
        if (m == 0) 
            s += "012345".charAt(q);
    }
    return s;
}

/* Base script written by Jaap Scherphuis, jaapsch a t yahoo d o t com */
Scramblers.prototype.scramblePyraminx = function(){
    var i, j, n, ls, t;
    
    seq = new Array();
    i = 0;
    
    var f2e = [[], [3, 2, 1, 2, 3, 1, 1, 2, 0, 1, 1, 2, 0, 2], [3, 2, 1, 2, 0, 2, 1, 1, 0, 2, 3, 1, 0, 2], [0, 1, 2, 2, 0, 2, 2, 1, 0, 2, 1, 1, 0, 1, 1, 2], [1, 1, 0, 2, 3, 2, 0, 1, 3, 1, 1, 2], [1, 2, 3, 1, 1, 1, 3, 2], [0, 2, 3, 2, 1, 1, 0, 2, 3, 1, 0, 2, 1, 2], [0, 1, 3, 2, 2, 2, 0, 2, 3, 2, 2, 1, 3, 2], [1, 1, 0, 1, 1, 2, 0, 2], [1, 2, 3, 2, 1, 1, 3, 1], [0, 2, 3, 2, 1, 1, 0, 2, 3, 1, 1, 2, 0, 2], [1, 2, 3, 2, 0, 2, 1, 1, 0, 2, 3, 1, 0, 2], [3, 1, 1, 2, 3, 2, 1, 1], [3, 1, 1, 1, 0, 1, 1, 2, 0, 2, 3, 2], [0, 1, 3, 2, 0, 1, 1, 2, 3, 1, 0, 1, 1, 1], [1, 2, 0, 2, 3, 2, 1, 1, 0, 2, 3, 1, 0, 2], [0, 1, 1, 1, 0, 2, 1, 2], [1, 1, 0, 2, 3, 1, 0, 1, 3, 2, 1, 2], [3, 2, 0, 2, 1, 1, 0, 2, 3, 1, 0, 2, 1, 2], [3, 1, 2, 2, 0, 1, 3, 2, 2, 1, 0, 2], [0, 1, 3, 1, 0, 1, 1, 1, 3, 2, 0, 1, 1, 2], [0, 2, 1, 1, 3, 1, 0, 1, 3, 2, 1, 2], [3, 1, 1, 1, 0, 2, 3, 2, 1, 2, 0, 1], [3, 2, 0, 1, 1, 2, 3, 2, 1, 1, 3, 2, 0, 2], [0, 2, 1, 1, 3, 2, 0, 1, 3, 1, 1, 2], [3, 1, 1, 2, 0, 2, 1, 2, 0, 1, 3, 2, 1, 2], [2, 2, 1, 1, 0, 2, 2, 1, 0, 1, 1, 2], [0, 1, 1, 2, 3, 1, 1, 1, 0, 2, 3, 2], [0, 2, 1, 1, 0, 2, 1, 2, 0, 2], [3, 2, 1, 2, 0, 2, 1, 2, 0, 1, 3, 1, 1, 2], [0, 1, 1, 1, 3, 2, 1, 1, 3, 1, 1, 1, 0, 2], [1, 2, 0, 1, 3, 1, 0, 2, 3, 2, 1, 1], [1, 2, 0, 2, 1, 2, 0, 1, 1, 2], [0, 2, 3, 1, 1, 1, 0, 1, 3, 2, 1, 2], [0, 1, 3, 2, 1, 2, 3, 1, 1, 1, 0, 2], [0, 1, 1, 2, 3, 1, 0, 2, 3, 2, 1, 1], [0, 2, 1, 1, 0, 1, 1, 2], [1, 1, 0, 2, 3, 1, 0, 2, 3, 2, 0, 2, 1, 2], [0, 1, 3, 2, 1, 2, 3, 1, 1, 2, 0, 2, 1, 2], [0, 1, 1, 2, 3, 1, 0, 1, 3, 2, 0, 1, 1, 1], [0, 1, 1, 1, 3, 2, 0, 1, 3, 1, 0, 1, 1, 2], [0, 1, 1, 2, 3, 2, 1, 1, 0, 2, 3, 1], [1, 1, 3, 1, 0, 2, 1, 2, 0, 1, 3, 2], [2, 1, 1, 1, 0, 2, 2, 2, 0, 1, 1, 2], [0, 1, 3, 2, 0, 2, 3, 1], [0, 1, 2, 2, 0, 1, 1, 1, 2, 1, 0, 1, 1, 2], [3, 2, 0, 1, 1, 1, 3, 1, 1, 2, 0, 2], [0, 2, 1, 2, 3, 1, 1, 2, 0, 1, 3, 2, 1, 2], [1, 1, 0, 1, 3, 2, 1, 2, 0, 2, 3, 1], [0, 1, 3, 2, 1, 1, 0, 1, 3, 1, 0, 1, 1, 2], [1, 2, 3, 1, 0, 2, 1, 2, 3, 2, 0, 1, 1, 2], [1, 2, 3, 2, 0, 1, 1, 1, 3, 1, 0, 2], [0, 1, 3, 2, 0, 2, 1, 2, 3, 1, 1, 1], [3, 1, 1, 1, 0, 1, 3, 1, 1, 2, 3, 1, 0, 2], [3, 1, 0, 2, 1, 2, 0, 1, 3, 2, 1, 1], [1, 1, 3, 1, 1, 1, 0, 2, 3, 2, 1, 1, 0, 1], [0, 1, 1, 1, 3, 2, 0, 2, 3, 1, 1, 2], [3, 1, 1, 1, 3, 1, 0, 1, 1, 2, 3, 1, 0, 2], [3, 2, 0, 1, 1, 1, 3, 1, 0, 2, 1, 2], [3, 1, 0, 2, 1, 2, 3, 2, 0, 1, 1, 1], [0, 1, 1, 1, 0, 1, 1, 2, 0, 1], [3, 1, 0, 1, 1, 2, 3, 2, 1, 1, 0, 2], [1, 1, 3, 2, 0, 2, 1, 2, 3, 1, 0, 1], [1, 2, 0, 1, 3, 2, 1, 1, 3, 1, 0, 2], [3, 1, 0, 1, 3, 2, 0, 2], [1, 2, 3, 1, 1, 2, 0, 1, 3, 2, 1, 2, 0, 2], [0, 1, 3, 2, 1, 1, 3, 1, 1, 2, 0, 2], [0, 1, 1, 1, 3, 1, 0, 2, 1, 1, 3, 2, 1, 1], [1, 1, 3, 2, 0, 1, 3, 1, 1, 2, 0, 2], [1, 2, 3, 1, 0, 1, 1, 1, 3, 2, 0, 2], [0, 2, 3, 2, 0, 2, 1, 1, 3, 1, 0, 2, 1, 2], [1, 1, 0, 1, 1, 1, 3, 1, 1, 1, 0, 2, 3, 2], [1, 2, 3, 1, 0, 1, 3, 2, 1, 2, 0, 2, 1, 2], [3, 1, 1, 1, 0, 1, 3, 2, 1, 2, 0, 2], [3, 2, 0, 2, 1, 2, 3, 1, 0, 1, 1, 1], [1, 2, 0, 2, 3, 2, 0, 2, 1, 1, 3, 1, 0, 2], [3, 1, 0, 1, 1, 1, 3, 2, 0, 2, 1, 2], [1, 1, 3, 1, 0, 1, 3, 2, 1, 2, 0, 2], [0, 1, 3, 2, 1, 1, 3, 1, 0, 2, 1, 2], [1, 2, 3, 2, 0, 2, 1, 2, 3, 1, 0, 1, 1, 2], [1, 1, 0, 2, 1, 1, 0, 1, 1, 1], [1, 2, 0, 2, 3, 1, 0, 2, 3, 2, 1, 1, 0, 2], [0, 1, 3, 1, 1, 1, 0, 1, 3, 2, 0, 1, 1, 2], [0, 1, 1, 2, 3, 2, 1, 1, 3, 1, 0, 2], [0, 2, 1, 2, 0, 1, 1, 1], [3, 2, 0, 2, 1, 2, 3, 1, 1, 2, 0, 1, 1, 2], [0, 1, 3, 1, 0, 2, 3, 2], [0, 1, 3, 1, 1, 1, 0, 2, 1, 1, 3, 2, 1, 1], [0, 1, 3, 2, 1, 1, 0, 1, 3, 1, 1, 2, 0, 1], [0, 2, 1, 2, 3, 1, 0, 1, 1, 1, 3, 2], [1, 1, 3, 2, 0, 1, 1, 2, 3, 1, 0, 2], [0, 1, 3, 2, 1, 2, 3, 2, 1, 1, 0, 2, 3, 2], [0, 2, 1, 2, 0, 1, 1, 2, 0, 1, 1, 2, 0, 2], [0, 2, 1, 2, 3, 1, 0, 1, 3, 2, 1, 1], [1, 1, 0, 1, 3, 2, 1, 2, 3, 1, 0, 2], [1, 2, 3, 2, 1, 1, 0, 1, 3, 1, 0, 2], [0, 2, 1, 2, 0, 2, 1, 2, 0, 2, 1, 2], [0, 2, 1, 2, 3, 2, 0, 1, 1, 1, 3, 1], [0, 1, 3, 1, 1, 1, 0, 2, 3, 2, 1, 2], [1, 2, 0, 2, 3, 2, 1, 2, 3, 1, 0, 1, 1, 2], [1, 1, 0, 2, 1, 2, 0, 1], [0, 2, 1, 1, 3, 1, 0, 2, 3, 2, 0, 2, 1, 2], [1, 1, 0, 1, 3, 1, 0, 1, 3, 2, 0, 1, 1, 2], [0, 2, 1, 2, 3, 2, 1, 2, 3, 1, 0, 1, 1, 2], [1, 2, 0, 2, 1, 1, 0, 1], [3, 1, 1, 1, 0, 2, 1, 1, 3, 2, 1, 1, 0, 1], [3, 2, 1, 1, 0, 1, 3, 1, 0, 2, 1, 2], [2, 1, 1, 2, 3, 1, 2, 2, 1, 1, 3, 2], [3, 1, 1, 2, 0, 2, 3, 2, 1, 1, 0, 1], [1, 2, 3, 1, 0, 2, 1, 1, 0, 1, 3, 2], [3, 2, 1, 1, 0, 1, 3, 1, 1, 2, 0, 2], [0, 2, 3, 2, 1, 2, 3, 2, 0, 1, 1, 1, 3, 2], [1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1], [1, 2, 3, 2, 0, 2, 1, 1, 3, 1, 0, 1], [1, 1, 0, 1, 3, 1, 1, 2, 0, 2, 3, 2], [3, 2, 1, 2, 0, 1, 1, 2, 3, 1, 0, 2, 1, 2], [3, 1, 1, 2, 3, 2, 0, 2, 1, 1, 0, 1], [1, 2, 3, 1, 0, 2, 3, 2, 1, 1, 0, 1], [0, 2, 3, 2, 1, 2, 3, 1, 0, 1, 1, 1], [3, 2, 1, 1, 3, 2, 0, 1, 3, 2, 1, 2, 0, 2]];
    var l4e = [[], [1, 1, 3, 2, 1, 2, 3, 2, 1, 1, 3, 2, 1, 2], [1, 1, 3, 1, 1, 2, 3, 1, 1, 1, 3, 1, 1, 2], [3, 1, 0, 1, 3, 2, 1, 1, 3, 2, 1, 2, 3, 1, 0, 2], [1, 2, 3, 1, 0, 2, 3, 1, 0, 1, 3, 2, 1, 1, 3, 2], [0, 1, 3, 2, 1, 1, 3, 2, 1, 2, 3, 1, 0, 2, 3, 1], [0, 1, 3, 1, 1, 1, 3, 2, 1, 2, 0, 2], [1, 2, 0, 2, 3, 2, 0, 1, 3, 1, 1, 1], [2, 2, 1, 2, 3, 2, 1, 1, 3, 1, 2, 1], [0, 1, 1, 1, 3, 1, 1, 2, 3, 2, 0, 2], [1, 2, 3, 2, 0, 2, 3, 1, 0, 1, 1, 1], [2, 2, 3, 2, 1, 2, 3, 1, 1, 1, 2, 1], [1, 1, 0, 2, 3, 1, 0, 1, 3, 2, 0, 1, 1, 2, 0, 2], [3, 2, 1, 1, 3, 2, 1, 2, 3, 1, 0, 2, 3, 1, 0, 1], [0, 2, 1, 1, 3, 2, 1, 2, 3, 1, 1, 2, 0, 1, 1, 1], [3, 1, 0, 2, 3, 1, 0, 1, 1, 1, 3, 2, 2, 1, 3, 2, 2, 2, 1, 2], [3, 2, 0, 2, 2, 2, 3, 1, 2, 2, 0, 2, 2, 2, 0, 2], [3, 1, 0, 1, 2, 1, 0, 1, 2, 1, 3, 2, 2, 1, 0, 1], [1, 1, 3, 2, 1, 2, 0, 2, 3, 2, 0, 1, 3, 2], [3, 2, 1, 1, 3, 2, 1, 2, 0, 2, 3, 2, 0, 1], [3, 1, 1, 1, 3, 2, 1, 2, 0, 2, 3, 2, 0, 1, 3, 1], [3, 2, 0, 2, 3, 1, 0, 1, 1, 1, 3, 1, 1, 2, 3, 2], [3, 1, 0, 2, 3, 1, 0, 1, 1, 1, 3, 1, 1, 2], [0, 2, 3, 1, 0, 1, 1, 1, 3, 1, 1, 2, 3, 1], [3, 2, 0, 2, 2, 2, 3, 1, 2, 1, 0, 1], [0, 1, 1, 2, 2, 1, 0, 1, 2, 2, 0, 1, 1, 1], [3, 1, 1, 2, 0, 1, 1, 1, 0, 1, 3, 2, 0, 1], [3, 1, 0, 1, 1, 1, 0, 1, 3, 2, 0, 2, 1, 2, 0, 2], [3, 1, 0, 2, 3, 2, 0, 1], [1, 1, 3, 1, 1, 2, 3, 1, 0, 2, 3, 1, 0, 1], [0, 1, 1, 2, 0, 2, 1, 1], [3, 1, 0, 2, 2, 2, 3, 2, 2, 1, 3, 2, 0, 1, 3, 1], [3, 2, 0, 2, 3, 1, 0, 1], [0, 2, 2, 1, 0, 2, 2, 2, 0, 2], [3, 1, 1, 1, 3, 2, 1, 2, 3, 1, 0, 2, 3, 2, 0, 1], [3, 1, 0, 2, 3, 1, 2, 2, 3, 1, 2, 1, 0, 1], [0, 2, 3, 1, 0, 1, 1, 1, 3, 2, 1, 2], [3, 2, 1, 1, 3, 1, 2, 2, 1, 1, 2, 1, 1, 1], [3, 2, 1, 1, 3, 1, 1, 2, 3, 1, 1, 1, 3, 2, 1, 2], [0, 1, 1, 1, 0, 1, 3, 1, 0, 2, 1, 2, 0, 2, 3, 2], [1, 1, 3, 2, 1, 2, 3, 1], [3, 1, 0, 2, 3, 1, 0, 1, 3, 2, 1, 1, 3, 1, 1, 2, 3, 1], [3, 1, 0, 1, 2, 1, 0, 1, 2, 2, 0, 1, 3, 2], [3, 1, 1, 1, 3, 2, 2, 1, 3, 2, 2, 2, 1, 2, 3, 1], [3, 1, 1, 1, 3, 1, 1, 2, 3, 1], [3, 2, 1, 2, 0, 1, 1, 1, 0, 2, 3, 1], [1, 2, 2, 2, 1, 2, 2, 2, 3, 2, 2, 2, 1, 2, 3, 1], [3, 1, 1, 1, 2, 1, 3, 1, 2, 2, 3, 1, 1, 2], [3, 2, 1, 1, 3, 1, 1, 2], [1, 2, 0, 1, 1, 1, 0, 2], [0, 2, 3, 2, 0, 1, 3, 2, 1, 1, 3, 2, 1, 2], [3, 2, 1, 1, 2, 1, 3, 1, 2, 2, 3, 1, 1, 2, 3, 2], [3, 1, 1, 1, 2, 1, 3, 2, 2, 2, 1, 2], [3, 2, 0, 1, 1, 2, 0, 2, 1, 2, 3, 1, 1, 2], [1, 2, 0, 1, 2, 2, 1, 2, 2, 1, 1, 2, 0, 2], [3, 2, 1, 2, 0, 2, 1, 2, 3, 1, 1, 1, 0, 1, 1, 1], [3, 1, 1, 1, 3, 2, 1, 2], [3, 2, 0, 2, 3, 1, 0, 1, 3, 2, 1, 1, 3, 1, 1, 2], [1, 1, 2, 2, 1, 1, 2, 1, 1, 1], [3, 2, 1, 1, 3, 2, 2, 1, 3, 2, 2, 2, 1, 2], [0, 2, 3, 1, 0, 1, 3, 2], [3, 2, 1, 2, 2, 2, 1, 2, 2, 1, 1, 2, 3, 1], [3, 2, 1, 1, 3, 2, 1, 2, 3, 1, 0, 2, 3, 2, 0, 1, 3, 2], [3, 2, 0, 2, 3, 1, 2, 2, 3, 1, 2, 1, 0, 1, 3, 2], [1, 1, 3, 2, 1, 2, 0, 2, 3, 1, 0, 1], [3, 1, 0, 2, 3, 2, 0, 1, 3, 2, 0, 2, 3, 1, 0, 1], [3, 1, 0, 2, 3, 2, 2, 1, 0, 2, 2, 2, 0, 2], [1, 2, 0, 2, 1, 2, 3, 2, 1, 1, 0, 1, 1, 1, 3, 1], [3, 2, 0, 2, 3, 2, 0, 1, 3, 2], [0, 1, 2, 1, 0, 1, 2, 1, 3, 1, 2, 1, 0, 1, 3, 2], [3, 1, 0, 1, 1, 2, 0, 2, 1, 1, 3, 2], [3, 2, 0, 2, 2, 2, 3, 2, 2, 1, 3, 2, 0, 1], [3, 2, 1, 1, 3, 2, 1, 2, 3, 2], [0, 1, 2, 1, 0, 1, 2, 2, 0, 1], [0, 1, 1, 1, 2, 2, 1, 1, 0, 1, 2, 1, 0, 1, 1, 1], [1, 1, 3, 2, 2, 1, 3, 2, 2, 2, 1, 2, 3, 2], [1, 1, 3, 1, 1, 2, 3, 2], [3, 1, 0, 2, 2, 2, 3, 2, 2, 2, 0, 2, 2, 2, 0, 2], [3, 1, 1, 2, 0, 1, 1, 1, 0, 2, 3, 2], [1, 1, 2, 1, 3, 1, 2, 2, 3, 1, 1, 2, 3, 1], [3, 1, 1, 1, 3, 2, 1, 1, 0, 1, 1, 1, 0, 2], [3, 2, 0, 1, 1, 1, 0, 1, 3, 1, 0, 2, 1, 2, 0, 2], [3, 2, 0, 2, 2, 2, 3, 2, 2, 1, 0, 1, 3, 2], [3, 1, 1, 1, 3, 2, 1, 2, 3, 2, 1, 1, 3, 1, 1, 2], [0, 2, 3, 2, 0, 1, 3, 1], [3, 2, 0, 1, 1, 2, 0, 2, 1, 1, 3, 1], [3, 2, 1, 1, 2, 1, 3, 1, 2, 1, 1, 1, 2, 1, 1, 1], [0, 2, 2, 2, 3, 2, 2, 1, 3, 2, 0, 1, 3, 2], [3, 1, 0, 2, 3, 1, 0, 1, 3, 1], [1, 2, 0, 2, 2, 1, 0, 2, 1, 2, 2, 2, 1, 2, 0, 2], [1, 2, 2, 2, 1, 2, 2, 1, 1, 2], [0, 2, 3, 1, 2, 2, 3, 1, 2, 1, 0, 1, 3, 1], [3, 2, 0, 2, 3, 1, 0, 2, 1, 2, 0, 2, 1, 1], [3, 1, 1, 1, 2, 1, 3, 1, 2, 2, 1, 2, 3, 1], [3, 1, 1, 2, 0, 2, 1, 2, 3, 2, 1, 1, 0, 1, 1, 1], [3, 2, 0, 2, 3, 1, 0, 1, 3, 1, 0, 2, 3, 2, 0, 1]];
    
    
    var AUFs = [3, 1, 0, 2, 7, 5, 4, 6];
    seq = f2e[Math.floor(Math.random() * 120)].concat(l4e[Math.floor(Math.random() * 96)]);
    for (var i = 0; i < 8; i++) {
        var dir = Math.floor(Math.random() * 3);
        if (dir > 0) 
            seq = seq.concat([AUFs[i], dir]);
    }
    
    var s = "";
    for (i = 0; i < seq.length; i += 2) {
        s += "LRBUlrbu".charAt(seq[i]);
        if (seq[i + 1] == 2) 
            s += "'";
        s += " ";
    }
    do {
    }
    while (s != (s = s.replace(/(.) \1 /g, "$1' ").replace(/(.)' \1' /g, "$1 ").replace(/(.)' \1 /g, "").replace(/(.) \1' /g, "")));
    return s;
}
